package com.xckj.service.impl;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.thoughtworks.qdox.model.JavaMethod;
import com.thoughtworks.qdox.model.JavaParameter;
import com.xckj.dao.MethodTreeMapper;
import com.xckj.dao.ProjectversionMapper;
import com.xckj.dto.MethodTreeDto;
import com.xckj.dto.ProjectversionDto;
import com.xckj.dto.TreeData;
import com.xckj.entity.InterfaceMethod;
import com.xckj.entity.MethodTree;
import com.xckj.entity.Projectversion;
import com.xckj.service.QueryMethodTreeService;
import com.xckj.service.impl.Main.DataItem;
import com.xckj.utils.ParseJavaMethod;
import com.xckj.utils.ReturnT;

/**
 * @description method_tree
 * @author yanchf
 * @date 2024-01-14
 */
@Service
public class QueryMethodTreeServiceImpl implements QueryMethodTreeService {

	@Resource
	private MethodTreeMapper methodTreeMapper;
	@Resource
	private ProjectversionMapper projectversionMapper;

	@Override
	public Map<String,Object> pageList(int offset, int pagesize) {

		List<MethodTree> pageList = methodTreeMapper.pageList(offset, pagesize);
		int totalCount = methodTreeMapper.pageListCount(offset, pagesize);

		List<MethodTreeDto> pageDtoList = new ArrayList<>();
		if(pageList != null) {
			int count = 1;
			for(MethodTree tree : pageList) {
				MethodTreeDto dto = new MethodTreeDto();	
				dto.setId(tree.getId());
				dto.setXh(count + "");
				dto.setLevel(tree.getLevels());
				dto.setMethodName(tree.getMethodName());
				dto.setNumber(tree.getMethodNumber());
				pageDtoList.add(dto);
				count++;
			}
		}
		// result
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("pageList", pageDtoList);
		result.put("totalCount", totalCount);
		return ReturnT.success(result);
	}

	@Override
	public Map<String, Object> children(String methodName) {
		List<MethodTree> pageList = methodTreeMapper.children(methodName);
		List<MethodTreeDto> pageDtoList = new ArrayList<>();
		if(pageList != null) {
			int count = 1;
			for(MethodTree tree : pageList) {
				MethodTreeDto dto = new MethodTreeDto();	
				dto.setId(tree.getId());
				dto.setXh(count + "");
				dto.setLevel(tree.getLevels());
				dto.setMethodName(tree.getMethodName());
				dto.setNumber(tree.getMethodNumber());
				pageDtoList.add(dto);
				count++;
			}
		}
		// result
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("pageList", pageDtoList);
		return ReturnT.success(result);
	}

	@Override
	public Map<String, Object> allData() {
		List<MethodTree> pageList = methodTreeMapper.queryAll();
		List<MethodTreeDto> pageDtoList = new ArrayList<>();
		List<TreeData> useChildList =  new ArrayList<>();
		if(pageList != null) {
			List<TreeData> treeDataList = new ArrayList<>();
			int count = 1;
			for(MethodTree tree : pageList) {
				TreeData data = new TreeData();
				data.setXh(count + "");
				data.setId(tree.getId());
				data.setLevel(tree.getLevels());
				data.setMethodName(tree.getMethodName());
				data.setNumber(tree.getMethodNumber());
				data.setParentName(StringUtils.isEmpty(tree.getParentId()) ? "" : tree.getParentId());
				treeDataList.add(data);
				count ++;
			}
			//组织树类型结构
			useChildList = createChildObjects(treeDataList, "");
		}
		// result
		Map<String, Object> result = new HashMap<String, Object>();
		result.put("pageList", useChildList);
		result.put("totalCount", 10);
		return ReturnT.success(result);
	}
	
	/**
	 * 组织树类型格式
	 * @param dataList
	 * @param parentName
	 * @return
	 */
    private static List<TreeData> createChildObjects(List<TreeData> dataList, String parentName) {
        List<TreeData> childList = new ArrayList<>();
        for (TreeData item : dataList) {
            if (item.getParentName().equals(parentName)) {
                List<TreeData> children = createChildObjects(dataList, item.getMethodName());
                item.setChildren(children);
                childList.add(item);
            }
        }
        return childList;
    }

	@Override
	public Map<String, Object> detail(String functionName) {
		Map<String, Object> result = new HashMap<String, Object>();
		if(StringUtils.isEmpty(functionName)) {
			result.put("content", "");
			result.put("lineCount", 0);
			return ReturnT.success(result);
		}
		List<Projectversion> pageList = projectversionMapper.pageList(0, 10);
		ParseJavaMethod parseJavaMethod = new ParseJavaMethod();
		String[] str = functionName.split(":");
		String packPath = str[0];
		String methodName = str[1];
		String useMethodName = methodName.substring(0, methodName.indexOf("("));
		String argsStr = methodName.substring(methodName.indexOf("(") + 1, methodName.indexOf(")"));
		String[] args = argsStr.split(",");
		String filePath = "";
		String usePackDir = packPath.substring(0, packPath.lastIndexOf("."));
		String filePackPath = usePackDir.replace(".", File.separator);
		if(pageList != null) {
			Projectversion projectInfo = pageList.get(0);
			String sourcePath = projectInfo.getSourcePath();
			filePath = sourcePath + File.separator + filePackPath;
		}
		String methodContent = "";
		int lineCount = 0;
		if(!StringUtils.isEmpty(filePath)) {
			List<JavaMethod> methods = parseJavaMethod.getMethInfo(filePath, packPath);
			if(methods != null) {
				List<JavaParameter> params = new ArrayList<JavaParameter>();
				boolean isMethodEqus = false;
				for(JavaMethod method : methods) {
					if(method.getName().equalsIgnoreCase(useMethodName)) {
						if(args.length == (method.getParameters().size())) {
							params = method.getParameters();
							isMethodEqus = true;
							
							//如果参数不一致跳出认为不一致
							int i = 0;
							for(JavaParameter param : params) {
								if(!param.getType().toString().equalsIgnoreCase(args[i])) {
									isMethodEqus = false;
								}
								i ++;
							}
							
							//方法名称和参数均一致
							if(isMethodEqus) {
								methodContent = method.getCodeBlock();
								lineCount += method.getSourceCode().split("\n").length;
								break;
							}
						}
					}
				}

			}
		}
		result.put("content", methodContent);
		result.put("lineCount", lineCount);
		return ReturnT.success(result);
	}
}